
import os
import sys

from distutils.core import setup
from distutils.errors import DistutilsFileError
from distutils.command.install_lib import install_lib
from distutils.command.install_data import install_data
from distutils.command.install_scripts import install_scripts

if sys.version_info < (2, 5):
    sys.exit("requires python 2.5 and above")

#===============================================================================
# Globals
#===============================================================================

data_dir_defined = False
scripts_dir_defined = False
s_version = "0.3.4"
app_dir = "" # dexen folder where the core, examples and libs are located.
app_dir_name = "dexen-%s"%(s_version)
 
for name in sys.argv[1:]:
    if name.startswith("--install-data"):
        data_dir_defined = True
    if name.startswith("--install-scripts"):
        scripts_dir_defined = True

#===============================================================================
# Helper functions
#===============================================================================
def is_python_25():
    return sys.version_info[0] == 2 and sys.version_info[1] == 5

#===============================================================================
# Custom Command Class
#===============================================================================
class my_install_scripts(install_scripts):
    def run(self):
        install_scripts.run(self)
        if os.name == 'nt':
            file_path = os.path.join(self.install_dir, "dexen_env.bat")
            f = open(file_path, "w")
            app_lib_dir = os.path.join(app_dir, "lib") 
            f.write("set PYTHONPATH=%s;%s;%%PYTHONPATH%%"%(app_dir, app_lib_dir))
            f.close()

class my_install_lib(install_lib):
    def _create_pth_file(self, file_path):
        f = open(file_path, "w")
        f.write(app_dir_name + "\n")
        f.write(os.path.join(app_dir_name, "lib"))
        f.close()

    def copy_tree_without_svn (self, src, dst):       
        if not os.path.isdir(src):
            raise DistutilsFileError, \
                  "cannot copy tree '%s': not a directory" % src
        try:
            names = os.listdir(src)
        except os.error, (_, errstr):
            raise DistutilsFileError, \
                  "error listing files in '%s': %s" % (src, errstr)
    
        self.mkpath(dst)
    
        outputs = []
    
        for n in names:
            src_name = os.path.join(src, n)
            dst_name = os.path.join(dst, n)
       
            if os.path.isdir(src_name):
                if not src_name.endswith(".svn"):
                    outputs.extend(self.copy_tree_without_svn(src_name, dst_name))
            else:
                self.copy_file(src_name, dst_name)
                outputs.append(dst_name)
    
        return outputs    
        
    def run(self):
        global app_dir, ext_libs
        file_path = os.path.join(self.install_dir, "dexen.pth")
        self.install_dir = os.path.join(self.install_dir, app_dir_name)
        app_dir = self.install_dir
        install_lib.run(self)
        for lib_name in ext_libs:
            src_dir = os.path.join("lib", lib_name) 
            dst_dir = os.path.join(self.install_dir, "lib", lib_name)
            if lib_name == "multiprocessing" and not is_python_25():
                continue
            self.copy_tree_without_svn(src_dir, dst_dir)
        if os.name != "nt":
            self._create_pth_file(file_path)

class my_install_data(install_data):
    def copy_tree_without_svn (self, src, dst):       
        if not os.path.isdir(src):
            raise DistutilsFileError, \
                  "cannot copy tree '%s': not a directory" % src
        try:
            names = os.listdir(src)
        except os.error, (_, errstr):
            raise DistutilsFileError, \
                  "error listing files in '%s': %s" % (src, errstr)
    
        self.mkpath(dst)
    
        outputs = []
    
        for n in names:
            src_name = os.path.join(src, n)
            dst_name = os.path.join(dst, n)
       
            if os.path.isdir(src_name):
                if not src_name.endswith(".svn"):
                    outputs.extend(self.copy_tree_without_svn(src_name, dst_name))
            else:
                self.copy_file(src_name, dst_name)
                outputs.append(dst_name)
    
        return outputs    
    
    def run(self):
        if not data_dir_defined:
            self.install_dir = app_dir
        # Copying data folders
        for data_dir in data_dirs:
            if os.name != "nt" and data_dir == "bin":
                continue 
            dst_dir = os.path.join(self.install_dir, data_dir)
            self.copy_tree_without_svn(data_dir, dst_dir)
        # Copying data files
        for data_file in data_files:
            self.copy_file(data_file, self.install_dir)
        

#===============================================================================
# 
#===============================================================================
_cmdclass = {
    "install_data" : my_install_data,
    "install_lib" : my_install_lib,
    "install_scripts" : my_install_scripts
}

_scripts = [
    os.path.join('scripts', 'dexen-cli.py'),
    os.path.join('scripts', 'dexen-node.py'),
    os.path.join('scripts', 'dexen-server.py')
]

if os.name == "nt":
    _scripts.append(os.path.join('bin', 'dexen-cli.bat'))
    _scripts.append(os.path.join('bin', 'dexen-node.bat'))
    _scripts.append(os.path.join('bin', 'dexen-server.bat'))
    _scripts.append(os.path.join('bin', 'dc.bat'))
    _scripts.append(os.path.join('bin', 'dn.bat'))
    _scripts.append(os.path.join('bin', 'ds.bat'))

_dexen_pkgs = [
    'dexen',
    'dexen.libs',
    'dexen.system',
    'dexen.system.client',
    'dexen.system.common',
    'dexen.system.node',
    'dexen.system.node.master',
    'dexen.system.node.master.mgrs',
    'dexen.system.node.slave',
    'dexen.system.registry',
    'dexen.system.server'
]

ext_libs = [
    'multiprocessing',
    'py2energyplus',
    'py2radiance',
    'py2z88',
    'rpyc',
    'shapely'
]

data_dirs = [
    'examples',
]

data_files = [
    'README.txt',
    'Changelog.txt',
    'LICENSE.txt'
]

#===============================================================================
# 
#===============================================================================
setup(
    name="dexen", 
    version=s_version, 
    license="GPL", 
    author="Patrick Janssen, Cihat Basol",
    description="Distributed Execution Environment",
    url="http://code.google.com/p/dexen",
    download_url="http://code.google.com/p/dexen/downloads/list",
    platforms="any",
    author_email="cihatbasol@gmail.com, patrick.ht.janssen@gmail.com",
    packages=_dexen_pkgs,
    data_files=[("", ["README.txt"])], # This is dummy, to be overriden. 
                                       # Needed to trigger the command.
    scripts=_scripts,
    cmdclass=_cmdclass
)

